package main

import (
	"fmt"
	"io"
	"net"
	"sync"
)

// 服务端对象
type Server struct {
	Ip        string
	Port      int
	OnlineMap map[string]*User
	mapLock   sync.RWMutex

	// 消息广播的channel
	Message chan string
}

// 创建一个Server接口
func NewServer(Ip string, Port int) *Server {
	server := &Server{
		Ip:        Ip,
		Port:      Port,
		OnlineMap: make(map[string]*User),
		Message:   make(chan string),
	}
	return server
}

// 监听Message中有消息时,立刻发送到所有用户的channel
func (this *Server) ListenMessage() {
	for {
		msg := <-this.Message

		// 把服务端chan中的msg分发到每个user的chan中
		this.mapLock.Lock()
		for _, user := range this.OnlineMap {
			user.C <- msg
		}
		this.mapLock.Unlock()
	}

}

// 广播消息
func (this *Server) BroadCast(user *User, msg string) {
	sendMsg := "[" + user.Addr + "]" + user.Name + ":" + msg

	this.Message <- sendMsg
}

func (this *Server) Handler(conn net.Conn) {
	// 创建用户
	user := NewUser(conn, this)

	// 用户上线，将用户加入到OnlineMap中
	user.Online()

	// 接收客户端发送的消息
	go func() {
		buf := make([]byte, 4096)
		for {
			// 读取用户发送的消息
			n, err := conn.Read(buf)
			if n == 0 {
				user.Offline()
				return
			}

			// 消息读取出错
			if err != nil && err != io.EOF {
				fmt.Println("Conn Read err: ", err)
				return
			}

			// 提取用户消息为string
			msg := string(buf[:n-1])

			// 处理用户发送的消息
			user.DoMessage(msg)

		}
	}()

	// 当前handler阻塞

}

// 启动服务器
func (this *Server) Start() {
	// socket listen
	listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", this.Ip, this.Port))
	if err != nil {
		fmt.Println("net listener err: ", err)
		return
	}

	// close listener
	defer listener.Close()

	// 启动监听Message的goroutine
	go this.ListenMessage()

	// listener accept
	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("listener accept err: ", err)
			continue
		}

		// do handler
		go this.Handler(conn)
	}

}
